# -*- coding: utf-8 -*-
"""
分类目录模块
"""
from flask import Blueprint, render_template, request,jsonify
from apps.common.utils.rights import authorize
from apps.common.utils.http import table_api, success_api, fail_api
from apps.common.utils.validate import str_escape
from apps.common import curd
from apps.modules.admin.models import Category
from apps.extensions import db
from apps.modules.admin.schemas import CategorySchema, CategoryOutSchema2
category_bp = Blueprint('category', __name__, url_prefix='/category')
@category_bp.get('/')
@authorize("cms:category:main")
def index():
    return render_template('cms/category/main.html')


@category_bp.post('/data')
@authorize("cms:category:main")
def data():
    category = Category.query.all()
    data = CategorySchema(many=True).dump(category)

    # 创建一个字典，用于存储每个节点的子节点
    tree = {}
    for item in data:
        item["children"] = []
        tree[item["id"]] = item

    # 构建树形结构
    root_nodes = []
    for item in data:
        parent_id = item["parent_id"] if item["parent_id"] != 0 else None
        if parent_id is None:
            root_nodes.append(item)
        else:
            if parent_id in tree:
                tree[parent_id]["children"].append(item)

    return table_api(msg="请求成功", data=root_nodes)



# 分类删除
@category_bp.delete('/remove/<int:id>')
@authorize("cms:category:remove", log=True)
def remove(id):
    # 执行删除操作
    try:
        success = delete_category_and_children(id)
        db.session.commit()
        
        if success:
            return success_api(msg="删除成功")
        else:
            return fail_api(msg="分类不存在")
    except Exception as e:
        db.session.rollback()
        return fail_api(msg=f"删除失败: {str(e)}")


# 批量删除分类
@category_bp.delete('/batchRemove')
@authorize("cms:category:remove", log=True)
def batch_remove():
    # 获取要删除的ID列表
    ids = request.form.getlist('ids[]') or request.json.get('ids', [])
    
    if not ids:
        return fail_api(msg="请选择要删除的分类")
    # 执行批量删除操作
    try:
        deleted_count = 0
        for category_id in ids:
            if delete_category_and_children(int(category_id)):
                deleted_count += 1
        
        db.session.commit()
        
        if deleted_count > 0:
            return success_api(msg=f"成功删除 {deleted_count} 个分类")
        else:
            return fail_api(msg="没有找到要删除的分类")
    except Exception as e:
        db.session.rollback()
        return fail_api(msg=f"批量删除失败: {str(e)}")

def delete_category_and_children(category_id):
    """递归删除分类及其所有子分类"""
    # 查找当前分类
    category = Category.query.filter_by(id=category_id).first()
    if not category:
        return False

    # 查找所有子分类
    children = Category.query.filter_by(parent_id=category_id).all()

    # 递归删除所有子分类
    for child in children:
        delete_category_and_children(child.id)

    # 删除当前分类
    Category.query.filter_by(id=category_id).delete()
    return True


# 分类新增页面
@category_bp.get('/add')
@authorize("cms:category:add", log=True)
def add():
    # 获取父级分类ID参数
    parent_id = request.args.get('parent_id', type=int, default=0)
    return render_template('cms/category/add.html', parent_id=parent_id)


# 分类编辑页面
@category_bp.get('/edit/<int:id>')
@authorize("cms:category:edit", log=True)
def edit(id):
    category = Category.query.filter_by(id=id).first()
    if not category:
        return fail_api(msg="分类不存在")
    return render_template('cms/category/edit.html', category=category)


# 分类保存
@category_bp.post('/save')
@authorize("cms:category:add", log=True)
def save():
    req_json = request.get_json(force=True)
    
    # 验证必填字段
    title = str_escape(req_json.get("title", "").strip())
    alias = str_escape(req_json.get("alias", "").strip())
    parent_id = req_json.get("parentId", 0)
    # 确保parent_id是整数类型
    if parent_id is not None:
        try:
            parent_id = int(parent_id)
        except (ValueError, TypeError):
            parent_id = 0

    desc = str_escape(req_json.get("desc", "").strip())
    
    if not title:
        return fail_api(msg="分类名称不能为空")
    if not alias:
        return fail_api(msg="别名不能为空")
    
    # 检查别名是否已存在
    existing_category = Category.query.filter_by(alias=alias).first()
    if existing_category:
        return fail_api(msg="别名已存在")
    
    # 检查父级分类是否存在（只有当parent_id不为0时才检查）
    if parent_id and parent_id != 0:
        parent_category = Category.query.filter_by(id=parent_id).first()
        if not parent_category:
            return fail_api(msg="父级分类不存在")
    
    try:
        category = Category(
            title=title,
            alias=alias,
            desc=desc,
            parent_id=parent_id
        )
        db.session.add(category)
        db.session.commit()
        return success_api(msg="分类添加成功")
    except Exception as e:
        db.session.rollback()
        return fail_api(msg=f"分类添加失败: {str(e)}")


# 分类更新
@category_bp.put('/update')
@authorize("cms:category:edit", log=True)
def update():
    req_json = request.get_json(force=True)
    
    category_id = req_json.get("categoryId")
    title = str_escape(req_json.get("title", "").strip())
    alias = str_escape(req_json.get("alias", "").strip())
    parent_id = req_json.get("parentId", 0)
    # 确保parent_id是整数类型
    if parent_id is not None:
        try:
            parent_id = int(parent_id)
        except (ValueError, TypeError):
            parent_id = 0
    desc = str_escape(req_json.get("desc", "").strip())
    
    if not category_id:
        return fail_api(msg="分类ID不能为空")
    if not title:
        return fail_api(msg="分类名称不能为空")
    if not alias:
        return fail_api(msg="别名不能为空")
    
    # 检查分类是否存在
    category = Category.query.filter_by(id=category_id).first()
    if not category:
        return fail_api(msg="分类不存在")
    
    # 检查别名是否已被其他分类使用（只有当别名发生变化时才检查）
    if alias != category.alias:
        existing_category = Category.query.filter_by(alias=alias).first()
        if existing_category and existing_category.id != category_id:
            return fail_api(msg="别名已存在")
    
    # 检查父级分类是否存在且不能是自己（只有当parent_id不为0时才检查）
    if parent_id and parent_id != 0:
        if parent_id == category_id:
            return fail_api(msg="父级分类不能是自己")
        parent_category = Category.query.filter_by(id=parent_id).first()
        if not parent_category:
            return fail_api(msg="父级分类不存在")
    
    try:
        category.title = title
        category.alias = alias
        category.desc = desc
        category.parent_id = parent_id
        
        db.session.commit()
        return success_api(msg="分类更新成功")
    except Exception as e:
        db.session.rollback()
        return fail_api(msg=f"分类更新失败: {str(e)}")


# 获取分类树数据（用于父级选择）
@category_bp.get('/tree')
@authorize("cms:category:main")
def tree():
    categories = Category.query.all()
    data = CategorySchema(many=True).dump(categories)
    
    # 返回扁平化的列表数据，dtree会根据parent_id自动构建树形结构
    return jsonify({
        "status": {
            "code": 200,
            "message": "获取成功"
        },
        "data": data
    })


# 获取分类选择数据（用于父级选择）
@category_bp.get('/selectParent')
@authorize("cms:category:main", log=True)
def select_parent():
    categories = Category.query.all()
    data = curd.model_to_dicts(schema=CategoryOutSchema2, data=categories)
    
    # 添加顶级分类选项
    data.append({"id": 0, "title": "顶级分类", "parent_id": -1})
    
    return jsonify({
        "status": {"code": 200, "message": "默认"},
        "data": data
    })